/*
 * =====================================================================================
 *
 *       Filename:  shell.c
 *
 *    Description:  test
 *
 *        Version:  1.0
 *        Created:  西元2011年01月13日 14時51分40秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  YOUR NAME (), 
 *        Company:  
 *
 * =====================================================================================
 */
/*
#include<unistd.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<assert.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<signal.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<dirent.h>
#include<string.h>
#include<errno.h>
#define POINT_SIZE 4
//#define PROMPT_ENVIRONMENT_VARIABLE "PROMPT"
#define COMMANDNUM 10000 
#define ENVNUM 64*/	
#include"shell.h"
/*struct envVar {
	char name[200];
	char content[200];
};
struct usr {
	char name[200];
	unsigned id;
}
struct commandInfo {
	int boolInFile;
	int boolOutFile;
	char argList[200];
	char commandName[200];
	char value[200];
	int pipeTo;
	int pipe2To;
	char inFile[80];
	char outFile[80];
	int booluse;
	int file_pipes[2];
	int pipeIn;
	char argv3[200];
};
struct lineInfo {
	int file_pipes[2];
	int using;
};*/
/*struct envVar env[ENVNUM]={"0","0"};
//char *prompt;
char *builtInCommand[]={
	"0",
	"printenv",
	"setenv"
};

struct commandInfo commandList[COMMANDNUM];
struct lineInfo linepipe[COMMANDNUM];
*/
/*void sendM2All(struct user * shared,char * m){
	int i=0;
								for(i=0;i<2;i++)
							{
							fprintf(stderr,"shared_stuff[%d].name=%s\n",i,shared_stuff[i].name);
							fprintf(stderr,"shared_stuff[%d].pid=%d\n",i,shared_stuff[i].pid);
							fprintf(stderr,"shared_stuff[%d].id=%d\n",i,shared_stuff[i].id);
							fprintf(stderr,"shared_stuff[%d].socket_fd=%d\n",i,shared_stuff[i].socket_fd);
							fprintf(stderr,"shared_stuff[%d].ip=%s\n",i,shared_stuff[i].ip);
						//	fprintf(stderr,"shared_stuff[%d].using=%d\n",i,shared_stuff[i].using);
							//fprintf(stderr,"\n");
						//}
	for(;i<31;i++){
		if(shared[i].using==1){
			printf("ffffffffffffffffffffffffffffffffffffffff\n");
			write(shared[i].socket_fd,m,strlen(m));
		}
	}
}*/
void who2(int *socket_fd,struct user *shared_stuff){
	//printf("aaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
	int i;
	char buffer[40960]="<ID>\t<nickname>\t<IP/port>\t<indicate me>\n";
	char s[20];
	for(i=0;i<31;i++){
		if(shared_stuff[i].using==1){
			  sprintf(s,"%d",i+1);
				strcat(buffer,s);
				strcat(buffer,"\t");
				strcat(buffer,shared_stuff[i].name);
				strcat(buffer,"\t");
			//	printf("1aaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
				strcat(buffer,shared_stuff[i].ip);
				strcat(buffer,"/");
				sprintf(s,"%d",shared_stuff[i].port);
				strcat(buffer,s);
				strcat(buffer,"\t");
				printf("%d,%d\n",socket_fd,shared_stuff[i].socket_fd);
				if(*socket_fd==shared_stuff[i].socket_fd)
					strcat(buffer,"<- me");
				strcat(buffer,"\n");
			}
	}
		//printf("aaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
	strcat(buffer,"% ");
	write(*socket_fd,buffer,strlen(buffer));
}
void setenv2(struct commandInfo *cmd,int *socket_fd){
	if(cmd->argv3[0]=='\0')return;
	char strsept[]=" \t";
	char *str_ptr=strtok(cmd->argv3,strsept);
	int i=0;	
	char name[2000];
	char value[200];
		strncpy(name,str_ptr,200);
		str_ptr=strtok(NULL,strsept);
		strncpy(value,str_ptr,200);	
						
	for(i=0;i<ENVNUM;i++){
		if(!strncmp(name,env[i].name,200)){
			strncpy(env[i].content,value,200);
			break;
		}
	}
	write(*socket_fd,"% ",2);
}
int socket_read_line_alloc(int sock, char* out) {
	int i = 0;
	char ch;
	for ( ; ; ) {
		if (recv(sock, &ch, 1, 0) == -1) {
			return -1;
		}
		if (ch == '\n') {
			out[i] = '\0';
			break;
		} else {
			if(ch=='\r')
				continue;
			out[i] = ch;
		}
		i++;
	}
	return i + 1;
}
void printenv( struct commandInfo *cmd,int *socket_fd){
	int i;
	char buffer[4096];
	if(cmd->argv3!=NULL&&cmd->argv3[0]!='\0'){
		for(i=0;i<32;i++){
			if(strlen(env[i].name)!=0&&!strcmp(env[i].name,cmd->argv3)){
				strncpy(buffer,cmd->argv3,4095);
				strcat(buffer,"=")/*,4095-strlen(cmd->argv3))*/;
				strcat(buffer,env[i].content)/*,4095-strlen(cmd->argv3)-1)*/;
				strcat(buffer,"\n% ")/*,4095-strlen(cmd->argv3)-1-strlen(env[i].content))*/;
				write(*socket_fd,buffer,strlen(buffer));
				break;
			}
		}					
	}
}
void name(struct commandInfo *cmd,int * socket_fd,struct user *shared_stuff,pid_t ppid){
	int i;
	for(i=0;i<31;i++){
		if(*socket_fd==shared_stuff[i].socket_fd){
			strcpy(shared_stuff[i].name,cmd->argv3);
			break;
		}
	}
	char m[1024]="*** User  from ";
	strcat(m,shared_stuff[i].ip);
	char s[128];
	sprintf(s,"/%d",shared_stuff[i].port);
	strcat(m,s);
	strcat(m," is named '");
	strcat(m,cmd->argv3);
	strcat(m,"'. ***");
	strcat(m,"\n% ");
	strcpy(shared_stuff[i].buffer,m);
	shared_stuff[i].toAll=32;
	kill(ppid,SIGUSR1);
	//sendM2All(shared_stuff,m);
}
void yell(struct commandInfo *cmd,int * socket_fd,struct user *shared_stuff,pid_t ppid){
	char m[10000]="*** ";
	int i;
	for(i=0;i<31;i++){
		if(*socket_fd==shared_stuff[i].socket_fd){
			break;
		}
	}
	//strcat(m,cmd->argv3);
	strcat(m,shared_stuff[i].name);
	strcat(m," yelled ***: ");
	strcat(m,cmd->argv3);
	strcat(m,"\n% ");
	strcpy(shared_stuff[i].buffer,m);
	shared_stuff[i].toAll=32;
	kill(ppid,SIGUSR1);
	//sendM2All(shared_stuff,m);
}
void tell(struct commandInfo *cmd,int * socket_fd,struct user *shared_stuff,pid_t ppid){
	int i;
	for(i=0;i<31;i++){
		if(*socket_fd==shared_stuff[i].socket_fd){
			break;
		}
	}
	char *	token=strtok(cmd->argv3," ");
	if(atoi(token)<32&&shared_stuff[atoi(token)-1].using==1){
		shared_stuff[i].toAll=atoi(token);
	
			char buffer[2048]="*** ";
			strcat(buffer,shared_stuff[i].name);
			strcat(buffer," told you ***: ");
			token=strtok(NULL," ");	
			strcat(buffer,token);
			strcat(buffer,"\n% ");
			strcpy(shared_stuff[i].buffer,buffer);
			
			write(*socket_fd,"% ",2);
			kill(ppid,SIGUSR1);
	}else{
			char buffer[256]="*** Error: user ";
			strcat(buffer,token);
			strcat(buffer," does not exist yet. ***\n% ");
			write(*socket_fd,buffer,strlen(buffer));
			
		}

}

/*
void executeBuiltInCommand(struct commandInfo *cmd,int * socket_fd,struct user *shared_stuff,pid_t ppid ){
	if(!strcmp(cmd->commandName,"printenv"))
		printenv(cmd,socket_fd);
	else if(!strcmp(cmd->commandName,"setenv")){
		setenv2(cmd,socket_fd);}
	else if(!strcmp(cmd->commandName,"who")){
		who2(socket_fd,shared_stuff);
		}
	else if(!strcmp(cmd->commandName,"name")){
		name(cmd,socket_fd,shared_stuff,ppid);
		}
	else if(!strcmp(cmd->commandName,"yell")){
		yell(cmd,socket_fd,shared_stuff,ppid);
		}
	else if(!strcmp(cmd->commandName,"tell")){
		tell(cmd,socket_fd,shared_stuff,ppid);
		}
}
*/

void executeBuiltInCommand(struct commandInfo *cmd,int * socket_fd){
	if(!strcmp(cmd->commandName,"printenv"))
		printenv(cmd,socket_fd);
	else if(!strcmp(cmd->commandName,"setenv")){
		setenv2(cmd,socket_fd);}

}
int isBuiltInCommand(struct commandInfo * cmd){
	int len=sizeof(builtInCommand)/POINT_SIZE;
	int i;
	for(i=1;i<len;i++)
		if(!strcmp(builtInCommand[i],cmd->commandName))
			return i;
	return 0;
}

void init_structCommand(){
	int i; 
	for(i=0;i<COMMANDNUM;i++){
			memset(&commandList[i],0,sizeof(struct commandInfo));
			memset(&linepipe[i],0,sizeof(struct lineInfo));
	}
}
int comIndex=0;
int first=0;
/*void parse(char *cmd,int *client_sockfd,struct user *shared_stuff,int id){
//printf("1dddddddddddddddddddddddddddddddd\n");
	int i=0;
	char *str_ptr;
	char strsept[]=" \t";
	str_ptr=strtok(cmd,strsept);
	while(str_ptr!=NULL){
		if(!strcmp(str_ptr,"exit")){
			close(*client_sockfd);
			shared_stuff[id].using=0;
			exit(0);
			}
		if(str_ptr[0]=='-'){
			strncpy(commandList[comIndex-1].argList,str_ptr,200);
		} 
		else if (str_ptr[0]=='<'){
			//printf("2dddddddddddddddddddddddddddddddd\n");
			if(str_ptr[1]!='\0'){
				//printf("parse %d\n",atoi(&str_ptr[1]));
				commandList[comIndex-1].ipc_in=atoi(&str_ptr[1]);
			//	printf("parse %d\n",atoi(&str_ptr[1]));
			}else {
			str_ptr=strtok(NULL,strsept);
			if(str_ptr==NULL)
				break;
			strncpy(commandList[comIndex-1].inFile,str_ptr,80);
			commandList[comIndex-1].boolInFile=1;
		  }
		}
		else if (str_ptr[0]=='>'){
			if(str_ptr[1]!='\0'){
				commandList[comIndex-1].ipc_pipe=1;
			}else{
			str_ptr=strtok(NULL,strsept);
			if(str_ptr==NULL)
				break;
			strncpy(commandList[comIndex-1].outFile,str_ptr,80);
			commandList[comIndex-1].boolOutFile=1;
		  }
		}
		else if (str_ptr[0]=='|'){
			i=0;
			commandList[comIndex-1].pipeTo=str_ptr[1]=='\0'?-1:(atoi(&str_ptr[1]));
		}
		else if (str_ptr[0]=='!'){
			i=0;
			commandList[comIndex-1].pipe2To=str_ptr[1]=='\0'?-1:(atoi(&str_ptr[1]));
		}		
		else {
			if(i==0){
				strncpy(commandList[comIndex].commandName,str_ptr,200);
				commandList[comIndex++].booluse=1;
				comIndex%=10000;
				i=1;
			}else {
			//	else{
				if(strlen(commandList[comIndex-1].argv3)!=0){	
					strcat(commandList[comIndex-1].argv3," ");
					strcat(commandList[comIndex-1].argv3,str_ptr);
				}
				else 
					strncpy(commandList[comIndex-1].argv3,str_ptr,200);
			//	}
			}
		}
		str_ptr=strtok(NULL,strsept);
	}


}
*/

void parse(char *cmd){
	int i=0;
	char *str_ptr;
	char strsept[]=" \t";
	str_ptr=strtok(cmd,strsept);
	while(str_ptr!=NULL){
		if(!strcmp(str_ptr,"exit"))exit(0);
		if(str_ptr[0]=='-'){
			strncpy(commandList[comIndex-1].argList,str_ptr,200);
		} 
		else if (str_ptr[0]=='<'){
			str_ptr=strtok(NULL,strsept);
			if(str_ptr==NULL)
				break;
			strncpy(commandList[comIndex-1].inFile,str_ptr,80);
			commandList[comIndex-1].boolInFile=1;
		}
		else if (str_ptr[0]=='>'){
			str_ptr=strtok(NULL,strsept);
			if(str_ptr==NULL)
				break;
			strncpy(commandList[comIndex-1].outFile,str_ptr,80);
			commandList[comIndex-1].boolOutFile=1;
		}
		else if (str_ptr[0]=='|'){
			i=0;
			commandList[comIndex-1].pipeTo=str_ptr[1]=='\0'?-1:(atoi(&str_ptr[1]));
		}
		else if (str_ptr[0]=='!'){
			i=0;
			commandList[comIndex-1].pipe2To=str_ptr[1]=='\0'?-1:(atoi(&str_ptr[1]));
		}		
		else {
			if(i==0){
				strncpy(commandList[comIndex].commandName,str_ptr,200);
				commandList[comIndex++].booluse=1;
				comIndex%=10000;
				i=1;
			}else {
			//	else{
				if(strlen(commandList[comIndex-1].argv3)!=0){	
					strcat(commandList[comIndex-1].argv3," ");
					strcat(commandList[comIndex-1].argv3,str_ptr);
				}
				else 
					strncpy(commandList[comIndex-1].argv3,str_ptr,200);
			//	}
			}
		}
		str_ptr=strtok(NULL,strsept);
	}
}
int checkIsExist(struct commandInfo * cmd,char *root){
	char tmp_root[1000];	
	char *	token=strtok(env[0].content,":");
	while(token!=NULL){
		strncpy(tmp_root,root,1000);
		strcat(tmp_root,token);
		strcat(tmp_root,"/");
		strcat(tmp_root,cmd->commandName);
		FILE *fp=fopen(tmp_root,"r");
		if(fp){
			strncpy(root,tmp_root,200);
			fclose(fp);
			return 1;
		}
		token=strtok(NULL,":");	
	}
	return 0;

}
void *shared_memory = (void *)0;
struct user *shared_stuff;
/*void handler(int signo) {
  switch (signo) {
    case SIGCHLD: {
			//int status = 0;
			int pid=wait(NULL);
			int i;
							for(i=0;i<2;i++)
							{
							fprintf(stderr,"shared_stuff[%d].name=%s\n",i,shared_stuff[i].name);
							fprintf(stderr,"shared_stuff[%d].pid=%d\n",i,shared_stuff[i].pid);
							fprintf(stderr,"shared_stuff[%d].id=%d\n",i,shared_stuff[i].id);
							fprintf(stderr,"shared_stuff[%d].socket_fd=%d\n",i,shared_stuff[i].socket_fd);
							fprintf(stderr,"shared_stuff[%d].ip=%s\n",i,shared_stuff[i].ip);
						//	fprintf(stderr,"shared_stuff[%d].using=%d\n",i,shared_stuff[i].using);
							//fprintf(stderr,"\n");
						//}
						char xd[1024];
					read(shared_stuff[0].user_pipes[0],xd,1024);
					printf(xd);
					printf("\n");
			for(i=0;i<31;i++){
				//if(shared_stuff){
					if(shared_stuff[i].pid==pid){
					close(shared_stuff[i].socket_fd);	
					char m[1024]="*** User '";
					strcat(m,shared_stuff[i].name);
					strcat(m,"' left. ***\n% ");
					
					shared_stuff[i].name[0]='\0';
	
	shared_stuff[i].pid=0;
	shared_stuff[i].id=0;
	shared_stuff[i].socket_fd=0;
	shared_stuff[i].ip[0]='\0';
	shared_stuff[i].port=0;
	shared_stuff[i].toAll=0;
	shared_stuff[i].buffer[0]='\0';
	shared_stuff[i].havaValue=0;
	shared_stuff[i].using=0;
				//	memset(&(shared_stuff[i]),0,sizeof(struct user));
					sendM2All(shared_stuff,m);
					//printf("dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\n");
					}
				//}
			}
			break;
   		}
   case SIGUSR1:{
   	int i;
   				for(i=0;i<31;i++){
					if(shared_stuff[i].toAll!=0){
						if(shared_stuff[i].toAll==32)
							sendM2All(shared_stuff,shared_stuff[i].buffer);
						else {
							write(shared_stuff[shared_stuff[i].toAll-1].socket_fd,shared_stuff[i].buffer,strlen(shared_stuff[i].buffer));
						}
						shared_stuff[i].toAll=0;
					}
			}
   break;	
  }
    default:
			fprintf(stderr, "Caught unknown signal: %d\n", signo);
			break;
    }
}
*/

int main(int argc,char **argv){
	chdir("/home/wei/ras");
	unsigned int line=0;
	int server_sockfd, client_sockfd;
	int server_len,client_len;
	char s[100];
	//-----------project 2
		pid_t parentid=getpid();
		void *shared_memory = (void *)0;
		struct user *shared_stuff;
		int shmid;
		shmid = shmget((key_t)KEY, sizeof(struct user)*31, 0666 | IPC_CREAT);
		if (shmid == -1) {
        fprintf(stderr, "shmget failed1\n");
        exit(EXIT_FAILURE);
   	}
   	shared_memory = shmat(shmid, (void *)0, 0);
   	if (shared_memory == (void *)-1) {
        fprintf(stderr, "shmat failed\n");
        exit(EXIT_FAILURE);
    }
    shared_stuff = (struct user *)shared_memory;
    memset(shared_stuff,0,sizeof(struct user)*31);
	//-------------------
	struct sockaddr_in server_address;
	struct sockaddr_in client_address;
	server_sockfd=socket(AF_INET,SOCK_STREAM,0);
	server_address.sin_family=AF_INET;
	server_address.sin_addr.s_addr=htonl(INADDR_ANY);
	server_address.sin_port=htons(atoi(argv[1]));
	server_len=sizeof(server_address);
	bind(server_sockfd,(struct sockaddr *)&server_address,server_len);
	listen(server_sockfd,5);
	int i;
/*	for(i=0;i<31;i++){
			if(pipe(shared_stuff[i].user_pipes)<0)return -1;
			int flags;
      flags=fcntl(shared_stuff[i].user_pipes[0],F_GETFL);
      flags |=O_NONBLOCK;
      fcntl(shared_stuff[i].user_pipes[0],F_SETFL,flags);
      flags=fcntl(shared_stuff[i].user_pipes[1],F_GETFL);
      flags |=O_NONBLOCK;
      fcntl(shared_stuff[i].user_pipes[1],F_SETFL,flags);
  }
  */
	while(1){
		client_len=sizeof(client_address);
		client_sockfd=accept(server_sockfd,(struct sockaddr *)&client_address,&client_len);
		
		//inet_ntop(client_address.ss_family,get_in_addr((struct sockaddr *)&client_address),s,sizeof s);
	//	printf("ff:%d,%s\n",client_sockfd,inet_ntoa(client_address.sin_addr));
		int i;
		for(i=0;i<32;i++){
			memset(env[i].name,0,sizeof(env[i].name));
			memset(env[i].content,0,sizeof(env[i].content));
		}
		//project 2------------------------
		for(i=0;i<31;i++){
			if(shared_stuff[i].using==0){
					shared_stuff[i].using=1;
					break;
				}
		}
	//	printf("i=%d\n",i);
		strcpy(shared_stuff[i].name,"(no name)");
		strcpy(shared_stuff[i].ip,inet_ntoa(client_address.sin_addr));
		shared_stuff[i].socket_fd=client_sockfd;
		//close(shared_stuff[i].socket_fd);
		char sport[256];
		shared_stuff[i].port=client_address.sin_port;
		char welcome[]="***************************************\r\n**Welcome to the information server. **\r\n***************************************\n";
		write(client_sockfd,welcome,strlen(welcome));
		char messages[128]="*** User '(no name)' entered from ";
		strcat(messages,inet_ntoa(client_address.sin_addr));
		char tmp[32];
		sprintf(tmp,"/%d\n",client_address.sin_port);
		strcat(messages,tmp);
		strcat(messages,"% ");
	//	sendM2All(shared_stuff,messages);
		//sprintf(sport,"%d",client_address.sin_port);
		//strcpy(shared_stuff[i].port,sport);
		//--------------------------------
		init_structCommand();	
		strncpy(env[0].name,"PATH",200);
		strncpy(env[0].content,"bin:.",200);
		int pid;
		if((pid=fork())==0){           
                        for(i=0;i<31;i++){
                                        if(shared_stuff[i].pid!=getpid()){
                                        close(shared_stuff[i].socket_fd);
                                        }
                        }
					if(shared_stuff[ix].pid!=getpid()){
					close(shared_stuff[ix].socket_fd);
					}
				
			}
			
			struct user *shared_stuff2=NULL;
			int shmid;
			void *shared_memory2=(void *) 0;
			shmid = shmget((key_t)KEY, sizeof(struct user)*31, 0666 | IPC_CREAT);
        if (shmid == -1){
        fprintf(stderr,"shmget failed\n");
        exit(EXIT_FAILURE);
       }
    	shared_memory2 = shmat(shmid,(void *) 0,0);
    	if (shared_memory2 == (void *)-1){
        fprintf(stderr,"shmat failed\n");
        exit(EXIT_FAILURE);
    	}
    	   	shared_stuff2 = (struct user *)shared_memory2;
    	 //  	printf("%s\n",shared_stuff2[i].name);
    //---------------------
			int id=i;
		//	printf("id=%d\n",id);
			char cmd[20000];
			int statval;
			//project 2
		//	char welcome[]="***************************************\r\n**Welcome to the information server. **\r\n***************************************\r\n% ";
		//	write(client_sockfd,welcome,strlen(welcome));
		//------
			while(1){
				//int i=socket_read_line_alloc(client_sockfd,cmd);
				socket_read_line_alloc(client_sockfd,cmd);
				line++;
				int first_command=1;
				//parse(cmd,&client_sockfd,shared_stuff2,id);
				parse(cmd);
			if(strlen(cmd)==0)	
				comIndex++;
				//fprintf(stderr,"%d=%d\n",first,comIndex);
					/*	for(i=first;i<comIndex;i++)
							{
							fprintf(stderr,"[%d]\n",line);
							fprintf(stderr,"commandList[%d].boolInfile=%d\n",i,commandList[i].boolInFile);
							fprintf(stderr,"commandList[%d].boolOutfile=%d\n",i,commandList[i].boolOutFile);
							//fprintf(stderr,"commandList[%d].boolBackground=%d\n",i,commandList[i].boolBackground);
							fprintf(stderr,"commandList[%d].argList=%s\n",i,commandList[i].argList);
							fprintf(stderr,"commandList[%d].commandName=%s\n",i,commandList[i].commandName);
							fprintf(stderr,"commandList[%d].pipeTo=%d\n",i,commandList[i].pipeTo);
							fprintf(stderr,"commandList[%d].pipeIn=%d\n",i,commandList[i].pipeIn);
							fprintf(stderr,"commandList[%d].pipe2To=%d\n",i,commandList[i].pipe2To);
							fprintf(stderr,"commandList[%d].inFile=%s\n",i,commandList[i].inFile);
							fprintf(stderr,"commandList[%d].outFile=%s\n",i,commandList[i].outFile);
							fprintf(stderr,"commandList[%d].booluse=%d\n",i,commandList[i].booluse);
							fprintf(stderr,"commandList[%d].value=%s\n",i,commandList[i].value);
							fprintf(stderr,"commandList[%d].argv3=%s\n",i,commandList[i].argv3);
							fprintf(stderr,"commandList[%d].ipc_in=%d\n",i,commandList[i].ipc_in);
							fprintf(stderr,"commandList[%d].ipc_pipe=%d\n",i,commandList[i].ipc_pipe);
							fprintf(stderr,"\n");
							}
	*/

				while(first!=comIndex){
					if(isBuiltInCommand(&commandList[first])){
					//	executeBuiltInCommand(&commandList[first],&client_sockfd,shared_stuff,parentid);
						executeBuiltInCommand(&commandList[first],&client_sockfd);
						memset(&commandList[first],0,sizeof(struct commandInfo));
					}
					else  {
						//project 2=--------------------------------
					//	if(pipe(shared_stuff2[0].user_pipes)<0)return -1;
						//	char tmtm[]="write in pipes \n";
						//	write(shared_stuff2[0].user_pipes[1],tmtm,strlen(tmtm));
							//close(shared_stuff2[0].user_pipes[1]);
							
						
						//--------------------------------------
						char buffer[4096]={0};
						int pfd[2]={0,0};
						if(pipe(pfd)<0)return -1;
						switch(commandList[first].pipeTo){
							case -1:
								if(commandList[first+1].pipeIn==0){
									if(pipe(commandList[first+1].file_pipes)<0){
										return -1;
									}
									else
										commandList[first+1].pipeIn=1;	
								}
							break;
							case 0:
							break;
							default:
							   if(linepipe[line+commandList[first].pipeTo].using==0){
								if(pipe(linepipe[line+commandList[first].pipeTo].file_pipes)<0){
									return -1;
								}
								else
									linepipe[line+commandList[first].pipeTo].using=1;
								}
	
						}
							
						switch(commandList[first].pipe2To){
							case -1:
								if(commandList[first+1].pipeIn==0){
									if(pipe(commandList[first+1].file_pipes)<0)
										return -1;
									else
										commandList[first+1].pipeIn=1;	
								}
							break;
							case 0:
							break;
							default:
								if(linepipe[line+commandList[first].pipe2To].using==0){
									if(pipe(linepipe[line+commandList[first].pipe2To].file_pipes)<0)
										return -1;
									else
										linepipe[line+commandList[first].pipe2To].using=1;
								}
						}
						
						int stderrOutPut=0;
						///------------------------------------------
						if(fork()==0){
							/*
							//	printf("1\n");
							if(first_command){
						//		first_command=0;
								if(linepipe[line].using==1){
						//			printf("7\n");
									dup2(linepipe[line].file_pipes[0],STDIN_FILENO);
									close(linepipe[line].file_pipes[0]);
								}
							}
							if (commandList[first].pipeIn==1){
							//	printf("8\n");
								dup2(commandList[first].file_pipes[0],STDIN_FILENO);
								close(commandList[first].file_pipes[0]);
							}//else if(commandList[first].ipc_in!=0){
								//printf("9\n");
								//char xd[1024];
								//read(shared_stuff2[commandList[first].ipc_in-1].user_pipes[0],xd,1024);
								//printf(xd);
					//printf("\n");
							//	dup2(shared_stuff2[commandList[first].ipc_in-1].user_pipes[0],STDIN_FILENO);
								
							//}
							if(commandList[first].pipeTo!=0){
								//printf("2\n");
								if(commandList[first].pipeTo==-1){
									dup2(commandList[(first+1)].file_pipes[1],STDOUT_FILENO);
									close(commandList[(first+1)].file_pipes[1]);
								}else{
									dup2(linepipe[line+commandList[first].pipeTo].file_pipes[1],STDOUT_FILENO);
									close(linepipe[line+commandList[first].pipeTo].file_pipes[1]);
								}
							}else if(commandList[first].pipe2To!=0){
						//		printf("3\n");
								if(commandList[first].pipe2To==-1){
									dup2(commandList[(first+1)].file_pipes[1],STDERR_FILENO);
									close(commandList[first+1].file_pipes[1]);
								}else{
									dup2(linepipe[(line+commandList[first].pipe2To)].file_pipes[1],STDERR_FILENO);
									close(linepipe[line+commandList[first].pipe2To].file_pipes[1]);
								}
								stderrOutPut=1;
							}//else if(commandList[first].ipc_pipe!=0){
						//		printf("4 , %d\n",id);
								
							//-project 2 -------------
							//dup2(shared_stuff2[id].user_pipes[1],STDOUT_FILENO);
							//shared_stuff2[id].havaValue=1;
							//--------------
						//	}
							else{
						//		printf("5\n");
								dup2(pfd[1],STDOUT_FILENO);
							}
							if(strlen(commandList[first].commandName)==0){
									printf("% ");
									return 0;
							}
							if(!stderrOutPut){
								dup2(pfd[1],STDERR_FILENO);
							}
							close(pfd[1]);
							if(commandList[first].boolOutFile==1){
								char fileStrTmp[1024]="/home/wei/ras/";
								strcat(fileStrTmp,commandList[first].outFile);
								int oldfd =open(fileStrTmp,(O_RDWR|O_CREAT),0644);
								dup2(oldfd,1);
								close(oldfd);
							}
							char *argv2[200];
							char root[200]="/home/wei/ras/";
							if(!checkIsExist(&commandList[first],root)){
								fprintf(stderr,"Unknown command: [%s].\r\n",commandList[first].commandName);
								return -1;
							}
							int tmp=0;
							int tmp_i;
							//char tmp_str[1000]="/home/wei/ras/";
							char argv4[20][200];
							for(tmp_i=0;;tmp_i++){
								if(tmp_i==0){
									argv2[tmp++]=(char *)&commandList[first].commandName;
									continue;
								}
								if(tmp_i==1){
									if(strlen(commandList[first].argList)!=0)
										argv2[tmp++]=(char *)&commandList[first].argList;
									continue;
								}
								char strsept[]=" \t";
								char *str_ptr=strtok(commandList[first].argv3,strsept);
								int i=0;	
						            while(str_ptr!=NULL){
								strncpy(argv4[i],str_ptr,200);
								argv2[tmp++]=(char *)&argv4[i++];
								str_ptr=strtok(NULL,strsept);
								}
								break;
								
							}
							argv2[tmp]=(char *)0;
							close(pfd[0]);
							execv(root,(char * const*)argv2);
							fprintf(stderr,"%s exe error\r\n",argv2[1]);
							exit(0);
					*/
					
							if(first_command){
						//		first_command=0;
								if(linepipe[line].using==1){
									dup2(linepipe[line].file_pipes[0],STDIN_FILENO);
									close(linepipe[line].file_pipes[0]);
								}
							}
							if (commandList[first].pipeIn==1){
								dup2(commandList[first].file_pipes[0],STDIN_FILENO);
								close(commandList[first].file_pipes[0]);
							}
							if(commandList[first].pipeTo!=0){
								if(commandList[first].pipeTo==-1){
									dup2(commandList[(first+1)].file_pipes[1],STDOUT_FILENO);
									close(commandList[(first+1)].file_pipes[1]);
								}else{
									dup2(linepipe[line+commandList[first].pipeTo].file_pipes[1],STDOUT_FILENO);
									close(linepipe[line+commandList[first].pipeTo].file_pipes[1]);
								}
							}else if(commandList[first].pipe2To!=0){
								if(commandList[first].pipe2To==-1){
									dup2(commandList[(first+1)].file_pipes[1],STDERR_FILENO);
									close(commandList[first+1].file_pipes[1]);
								}else{
									dup2(linepipe[(line+commandList[first].pipe2To)].file_pipes[1],STDERR_FILENO);
									close(linepipe[line+commandList[first].pipe2To].file_pipes[1]);
								}
								stderrOutPut=1;
							}else{
								dup2(pfd[1],STDOUT_FILENO);
							}
							if(strlen(commandList[first].commandName)==0){
									printf("% ");
									return 0;
							}
							if(!stderrOutPut){
								dup2(pfd[1],STDERR_FILENO);
							}
							close(pfd[1]);
							if(commandList[first].boolOutFile==1){
								char fileStrTmp[1024]="/home/wei/ras/";
								strcat(fileStrTmp,commandList[first].outFile);
								int oldfd =open(fileStrTmp,(O_RDWR|O_CREAT),0644);
								dup2(oldfd,1);
								close(oldfd);
							}
							char *argv2[200];
							char root[200]="/home/wei/ras/";
							if(!checkIsExist(&commandList[first],root)){
								fprintf(stderr,"Unknown command: [%s].\r\n",commandList[first].commandName);
								return -1;
							}
							int tmp=0;
							int tmp_i;
							char tmp_str[1000]="/home/wei/ras/";
							char argv4[20][200];
							for(tmp_i=0;;tmp_i++){
								if(tmp_i==0){
									argv2[tmp++]=(char *)&commandList[first].commandName;
									continue;
								}
								if(tmp_i==1){
									if(strlen(commandList[first].argList)!=0)
										argv2[tmp++]=(char *)&commandList[first].argList;
									continue;
								}
								char strsept[]=" \t";
								char *str_ptr=strtok(commandList[first].argv3,strsept);
								int i=0;	
						            while(str_ptr!=NULL){
								strncpy(argv4[i],str_ptr,200);
								argv2[tmp++]=(char *)&argv4[i++];
								str_ptr=strtok(NULL,strsept);
								}
								break;
								
							}
							argv2[tmp]=(char *)0;
							close(pfd[0]);
							execv(root,(char * const*)argv2);
							fprintf(stderr,"%s exe error\r\n",argv2[1]);
							exit(0);				
						}else {
							wait(&statval);
							if(first+1==comIndex){
								if(linepipe[line+1].using==1){
									close(linepipe[line+1].file_pipes[1]);	
								}
								if(linepipe[line].using==1)
									close(linepipe[line].file_pipes[0]);
							}
							if(commandList[first].pipeTo==-1||commandList[first].pipe2To==-1)
									close(commandList[first+1].file_pipes[1]);
							close(pfd[1]);		
							first_command=0;

						if(commandList[first].pipeIn){
							close(commandList[(first)].file_pipes[0]);
						}

								int len=read(pfd[0],buffer,4095);
								if(strlen(buffer)!=0){
									if(buffer[len-1]!='\n')
										strcat(buffer,"\r\n");
									buffer[len+4]='\0';
								}

								write(client_sockfd,buffer,strlen(buffer));
						/*	}else*/ 
							if((first+1)==comIndex){
								write(client_sockfd,"% ",2);
							}
								close(pfd[0]);
							memset(&commandList[first],0,sizeof(struct commandInfo));
						}
					}
					first++;
					first%=10000;
				}
			}
		}//if(fork)
		else{
	//		signal(SIGCHLD, handler);
//			signal(SIGUSR1, handler);
			
//			shared_stuff[i].pid=pid;
		//	printf("father :%d   %x\n",((struct user *)shared_memory)[i].pid,shared_stuff);
			//wait(NULL);
			//waitpid(pid,NULL,WNOHANG);
		}
		//close(client_sockfd);
	}//while(1)
	close(client_sockfd);
}
